package io.github.junxworks.qt.config.ds;

import java.util.Collection;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import com.google.common.collect.Range;
import com.google.common.collect.Sets;

public class YearTableShardingAlgorithm implements StandardShardingAlgorithm<String> {

	@Override
	public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
		String date = shardingValue.getValue();
		if (date == null) {
			throw new UnsupportedOperationException("Date column[" + shardingValue.getColumnName() + "] value can not be null");
		}
		String year = date.substring(0, 4);
		String suffix = getSuffix(year);
		for (String name : availableTargetNames) {
			if (name.endsWith(suffix)) {
				return name;
			}
		}
		throw new UnsupportedOperationException("Can not found available target name for suffix" + suffix);
	}

	@Override
	public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> shardingValue) {
		Range<String> dates = shardingValue.getValueRange();
		YearRange[] yrs = YearRange.values();
		Set<String> suffix = Sets.newHashSet();
		for (YearRange yr : yrs) {
			if (dates.isConnected(Range.closed(yr.getBegin(), yr.getEnd()))) {
				suffix.add(yr.getYear());
			}
		}
		if (!suffix.isEmpty()) {
			return availableTargetNames.parallelStream().filter(n -> {
				String s = n.substring(n.length() - 4);
				return suffix.contains(s);
			}).collect(Collectors.toList());
		}
		throw new UnsupportedOperationException("Can not found available target name for range[" + dates.toString() + "]");
	}

	private String getSuffix(String year) {
		int endWith = Integer.valueOf(year.substring(3));
		if (endWith >= 5) {
			endWith = 5;
		} else {
			endWith = 0;
		}
		return year.substring(0, 3) + endWith;
	}

	@Override
	public void init(Properties props) {
	}

}
